#ifndef TC_CHAIKINOSCILLATOR_HPP
#define TC_CHAIKINOSCILLATOR_HPP

/** \file ChaikinOscillator.hpp
 * Definition of the function template ChaikinOscillator.
 *
 * (C) Copyright 2003-2006 by Semih Cemiloglu
 * All rights reserved, see COPYRIGHT file for details.
 *
 * $Id: ChaikinOscillator.hpp 110 2006-06-19 03:38:33Z semihc $
 *
 *
 */


#include <vector>
#include "TA.hh"
#include "DBC.hpp"
#include "MAExpon.hpp"

namespace TC {

  //! Chaikin Oscillator function
  TC_EXPORT template <typename InputIterator,
                      typename OutputIterator,
                      class Adaptor>
  void ChaikinOscillator(InputIterator fromPos,
			 InputIterator fromEnd,
			 OutputIterator toPos,
			 const Adaptor adaptor)
  {
    // Accumulation/Distribution value
    register TAfp_t ad = 0.0;

    typename Adaptor::Price_t cls, hi, lo;
    typename Adaptor::Volume_t vol;

    // AD line
    std::vector<TAfp_t> ad_line; 

    for(; fromPos!=fromEnd; ++fromPos) {
      cls = adaptor.cls(*fromPos);
      vol = adaptor.vol(*fromPos);
      hi = adaptor.hi(*fromPos);
      lo = adaptor.lo(*fromPos);
      // Calculate accumulation distribution value
      ad += (((cls-lo)-(hi-cls))/(hi-lo))* vol;
      // Record AD line value
      ad_line.push_back( ad );
    } // end for

    // 3-period exponential average of AD line
    std::vector<TAfp_t> ad_ema3;
    // 10-period exponential average of AD line
    std::vector<TAfp_t> ad_ema10;

    ad_ema3.reserve( ad_line.size() );
    ad_ema10.reserve( ad_line.size() );

    MAExpon(ad_line.begin(), ad_line.end(),
	    std::back_inserter(ad_ema3), 3,
	    ArrayAdaptor<TAfp_t>());

    MAExpon(ad_line.begin(), ad_line.end(),
	    std::back_inserter(ad_ema10), 10,
	    ArrayAdaptor<TAfp_t>());

    TC_ASSERT(ad_line.size() == ad_ema3.size());
    TC_ASSERT(ad_line.size() == ad_ema10.size());
      
    for(unsigned i=0; i<ad_line.size(); ++i) 
      *toPos++ = ad_ema3[i] - ad_ema10[i];
  }

} // end namespace


#endif /* Include guard */
